package br.ufpe.cin.msc.jrsj2.recommender.algorithm.cf;

import java.util.ArrayList;
import java.util.List;

import br.ufpe.cin.msc.jrsj2.recommender.algorithm.RecommendationAlgorithm;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.dao.DAOFactory;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.dao.ProfileDAO;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.domain.Client;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.domain.Profile;
import br.ufpe.cin.msc.jrsj2.recommender.persistence.domain.Program;

public class ItemItemConsineBased extends RecommendationAlgorithm implements
		CollaborativeFiltering {

	private ProfileDAO profileDAO;

	public ItemItemConsineBased(Client activeClient, List<Program> itens,
			List<Profile> activeProfileList) {
		super(activeClient, itens, activeProfileList);
		profileDAO = DAOFactory.getDAOFactory().getProfileDAO();
	}

	@Override
	public List<Program> getRecommendations(int size) {
		List<Program> recommendations = new ArrayList<Program>();

		for (Program i1 : itens) {
			List<Profile> p1 = profileDAO.findProfileByProgram(i1);
			for (Program i2 : itens) {
				if (i1 != i2) {
					List<Profile> p2 = profileDAO.findProfileByProgram(i1);
					double similarity = this.calculateSimilarity(p1, p2);

					if (similarity > 0.5)
						recommendations.add(i1);
				}
			}
		}

		return recommendations;
	}

	private double calculateSimilarity(List<Profile> r1, List<Profile> r2) {
		double numerator = 0;
		double denominator;
		double powSum1 = 0;
		double powSum2 = 0;

		for (int i = 0; i < r1.size(); i++) {
			powSum1 += Math.pow(r1.get(i).getRating(), 2);
			powSum2 += Math.pow(r2.get(i).getRating(), 2);

			numerator += r1.get(i).getRating() * r2.get(i).getRating();
		}

		denominator = Math.sqrt(powSum1) * Math.sqrt(powSum2);

		return numerator / denominator;
	}

}
